package machineLearning;

import java.util.ArrayList;

import data.RTEData;
import data.RTEPreprocessedData;

import weka.classifiers.Classifier;
import weka.classifiers.Evaluation;
import weka.classifiers.bayes.NaiveBayes;
import weka.classifiers.lazy.IBk;
import weka.core.*;

public class ClassificationCrossValidation {

	public void classify() {

		ArrayList<RTEPreprocessedData> preprocessedData = RTEPreprocessedData.rtePreprocessedDataList;
		ArrayList<RTEData> data = RTEData.RTEDataList;
		
		Attribute wordMatch  = new Attribute("WordMatch");
		Attribute lemmaMatch = new Attribute("LemmaMatch");
		Attribute lemmaPosTagMatch = new Attribute("LemmaPosTagMatch");
		Attribute bigramMatch = new Attribute("BiGramMatch");
		
		FastVector entailmentValue = new FastVector();
		entailmentValue.addElement("yes");
		entailmentValue.addElement("no");
		
		Attribute classAttribute = new Attribute("entailment", entailmentValue);
		
		FastVector featureVector = new FastVector();
		featureVector.addElement(wordMatch);
		featureVector.addElement(lemmaMatch);
		featureVector.addElement(lemmaPosTagMatch);
		featureVector.addElement(bigramMatch);
		featureVector.addElement(classAttribute);
		
		int size = (int)Math.floor(data.size() * (float)1/10);
		Instances trainingSet = new Instances("training", featureVector, size);
		trainingSet.setClassIndex(4);

		double averageScore = 0;
		
		for(int j = 0; j < 10; j++) {
			int startIndex = j * size;
			Instances dataSet = new Instances("data", featureVector, size);
			dataSet.setClassIndex(4);
			
			//add test data
			for(int i = 0; i < size; i++) {
				Instance instance = new Instance(featureVector.size());
				instance.setValue((Attribute)featureVector.elementAt(0), data.get(startIndex+i).getWordMatchPercentage());
				instance.setValue((Attribute)featureVector.elementAt(1), preprocessedData.get(startIndex+i).getLemmaMatchPercentage());
				instance.setValue((Attribute)featureVector.elementAt(2), preprocessedData.get(startIndex+i).getLemmaPosTagMatchPercentage());
				instance.setValue((Attribute)featureVector.elementAt(3), preprocessedData.get(startIndex+i).getBiGramMatchPercentage());
				instance.setValue((Attribute)featureVector.elementAt(4), preprocessedData.get(startIndex+i).isEntailment() ? "yes" : "no");
				dataSet.add(instance);
			}
			
			//add training data from 0 to the start of test data
			for(int i = 0; i < startIndex; i++) {
				Instance instance = new Instance(featureVector.size());
				instance.setValue((Attribute)featureVector.elementAt(0), data.get(i).getWordMatchPercentage());
				instance.setValue((Attribute)featureVector.elementAt(1), preprocessedData.get(i).getLemmaMatchPercentage());
				instance.setValue((Attribute)featureVector.elementAt(2), preprocessedData.get(i).getLemmaPosTagMatchPercentage());
				instance.setValue((Attribute)featureVector.elementAt(3), preprocessedData.get(i).getBiGramMatchPercentage());
				instance.setValue((Attribute)featureVector.elementAt(4), preprocessedData.get(i).isEntailment() ? "yes" : "no");

				trainingSet.add(instance);
			}
			
			//add training data from end of test data to end of all the data
			for(int i = startIndex + size; i < data.size(); i++) {
				Instance instance = new Instance(featureVector.size());
				instance.setValue((Attribute)featureVector.elementAt(0), data.get(i).getWordMatchPercentage());
				instance.setValue((Attribute)featureVector.elementAt(1), preprocessedData.get(i).getLemmaMatchPercentage());
				instance.setValue((Attribute)featureVector.elementAt(2), preprocessedData.get(i).getLemmaPosTagMatchPercentage());
				instance.setValue((Attribute)featureVector.elementAt(3), preprocessedData.get(i).getBiGramMatchPercentage());
				instance.setValue((Attribute)featureVector.elementAt(4), preprocessedData.get(i).isEntailment() ? "yes" : "no");

				trainingSet.add(instance);
			}
			
			Classifier model = new IBk(11);
			try {
				model.buildClassifier(trainingSet);
				Evaluation testClassifier = new Evaluation(trainingSet);
				
				testClassifier.evaluateModel(model, dataSet);
				averageScore += testClassifier.correct() / (float)size;
				
				
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		averageScore /= 10; 
		
		System.out.println("3-c Machine learning: Cross validation average score = " + averageScore);
	}
}
